#include <stdfin/distribution/normal.hpp>

#define BOOST_TEST_MODULE stdfin_distribution_normal
#include <boost/test/included/unit_test.hpp>
#include <boost/test/floating_point_comparison.hpp>

BOOST_AUTO_TEST_SUITE(distribution_normal)

BOOST_AUTO_TEST_CASE( distribution_normal_cdf_test )
{
    // At wolfram. normal_cdf(z) = 0.5 + 0.5*erf(z/sqrt(2))
    // http://www.wolframalpha.com/input/?i=0.5%2B0.5*erf%284.1%2Fsqrt%282%29%29
    double tol = 1E-15;
    BOOST_CHECK_SMALL( stdfin::normal_cdf(0.0) - 0.5, tol); 
    BOOST_CHECK_SMALL( stdfin::normal_cdf(0.5) - 0.6914624612740131036377046106083377398836021755545779, tol ); 
    BOOST_CHECK_SMALL( stdfin::normal_cdf(0.9) - 0.8159398746532405114458021991185615871060480707909392, tol ); 
    BOOST_CHECK_SMALL( stdfin::normal_cdf(2.3) - 0.9892758899783241946076445161371854584500271840698063, tol ); 
    BOOST_CHECK_SMALL( stdfin::normal_cdf(4.1) - 0.9999793424930874532612047455405301339444894838335954, tol ); 

    BOOST_CHECK_SMALL( stdfin::normal_cdf(-0.5) - (1.0 - stdfin::normal_cdf(0.5)), tol ); 
    BOOST_CHECK_SMALL( stdfin::normal_cdf(-0.9) - (1.0 - stdfin::normal_cdf(0.9)), tol ); 
    BOOST_CHECK_SMALL( stdfin::normal_cdf(-2.3) - (1.0 - stdfin::normal_cdf(2.3)), tol ); 
    BOOST_CHECK_SMALL( stdfin::normal_cdf(-4.1) - (1.0 - stdfin::normal_cdf(4.1)), tol ); 
}

BOOST_AUTO_TEST_CASE( distribution_normal_pdf_test )
{
    // At wolfram. normal_pdf(z) = exp(-0.5*(z^2))/sqrt(2*pi)
    // http://www.wolframalpha.com/input/?i=0.5%2B0.5*erf%284.1%2Fsqrt%282%29%29
    double tol = 1E-15;
    BOOST_CHECK_SMALL( stdfin::normal_pdf(0.0) - 0.3989422804014326779399460599343818684758586311649346, tol); 
    BOOST_CHECK_SMALL( stdfin::normal_pdf(0.5) - 0.3520653267642994777746804415965176531103151803757119, tol ); 
    BOOST_CHECK_SMALL( stdfin::normal_pdf(0.9) - 0.2660852498987548218203615226256120461647898274009691, tol ); 
    BOOST_CHECK_SMALL( stdfin::normal_pdf(2.3) - 0.0283270377416011720289791394900951225275113150102904, tol ); 
    BOOST_CHECK_SMALL( stdfin::normal_pdf(4.1) - 0.0000892616571771328647261494574196848992427003190873, tol ); 

    BOOST_CHECK_SMALL( stdfin::normal_pdf(-0.5) - stdfin::normal_pdf(0.5), tol ); 
    BOOST_CHECK_SMALL( stdfin::normal_pdf(-0.9) - stdfin::normal_pdf(0.9), tol ); 
    BOOST_CHECK_SMALL( stdfin::normal_pdf(-2.3) - stdfin::normal_pdf(2.3), tol ); 
    BOOST_CHECK_SMALL( stdfin::normal_pdf(-4.1) - stdfin::normal_pdf(4.1), tol ); 
}

BOOST_AUTO_TEST_SUITE_END()
